﻿using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
using AutoPoco;
using AutoPoco.DataSources;
using AutoPoco.Engine;
using InvoiceProject.Controllers;
using InvoiceProject.Models;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting.Web;
using InvoiceProject.Enums;
using Moq;
using NUnit.Framework;
using TestContext = Microsoft.VisualStudio.TestTools.UnitTesting.TestContext;

namespace InvoiceProject.Tests.BusinessUnitTests
{




        [TestClass()]
        public class WhenConstructingBusiness
        {

            [TestMethod()]
            public void AddressShouldNotBeNull()
            {
                var business = new Business();
                business.Address.ShouldNotEqual(null);
            }


        }

        [TestClass()]
        public class WhenSavingBusiness
        {

            private static IGenerationSessionFactory AddressGenerationSessionFactory { get; set; }
            private static IGenerationSessionFactory BusinessGenerationSessionFactory { get; set; }

            private TestContext testContextInstance;

            /// <summary>
            ///Gets or sets the test context which provides
            ///information about and functionality for the current test run.
            ///</summary>
            public Microsoft.VisualStudio.TestTools.UnitTesting.TestContext TestContext
            {
                get { return testContextInstance; }
                set { testContextInstance = value; }
            }

            [ClassInitialize]
            public static void MyClassInitialize(Microsoft.VisualStudio.TestTools.UnitTesting.TestContext testContext)
            {
                AddressGenerationSessionFactory = AutoPocoContainer.Configure(x =>
                                                                                  {
                                                                                      x.Conventions(
                                                                                          c => c.UseDefaultConventions());
                                                                                      x.AddFromAssemblyContainingType
                                                                                          <Address>();
                                                                                      x.Include<Address>()
                                                                                          .Setup(i => i.Id).Use
                                                                                          <LongIdSource>()
                                                                                          .Setup(i => i.AddressLine1).
                                                                                          Use
                                                                                          <RandomStringSource>(1, 2)
                                                                                          .Setup(i => i.AddressLine2).
                                                                                          Use
                                                                                          <DefaultStringSource>()
                                                                                          .Setup(i => i.PostCode).Use
                                                                                          <IntegerSource>(2000, 2300)
                                                                                          .Setup(i => i.State).Use
                                                                                          <RandomStringSource>(2, 3)
                                                                                          .Setup(i => i.Suburb).Use
                                                                                          <CitySource>();
                                                                                  });


                BusinessGenerationSessionFactory = AutoPocoContainer.Configure(x =>
                                                                                   {
                                                                                       x.Conventions(
                                                                                           c =>
                                                                                           c.UseDefaultConventions());
                                                                                       x.AddFromAssemblyContainingType
                                                                                           <Business>();
                                                                                       x.Include<Business>()
                                                                                           .Setup(i => i.Id).Use
                                                                                           <LongIdSource>()
                                                                                           .Setup(i => i.ABN).Use
                                                                                           <RandomStringSource>()
                                                                                           .Setup(i => i.Email).Use
                                                                                           <EmailAddressSource>()
                                                                                           .Setup(i => i.Phone).Use
                                                                                           <RandomStringSource>();
                                                                                   }

                    );

            }


            [TestMethod()]
            public void ShouldBeSuccessfullWhenBusinessIsValid()
            {

                var session = AddressGenerationSessionFactory.CreateSession();
                var address = session.Single<Address>()
                    .Impose(x => x.Id, 0)
                    //.Impose(x => x.DateCreated, new DateTime())
                    .Impose(x => x.DateModified, new DateTime())
                   // .Impose(x => x.UserCreated, "")
                    .Impose(x => x.UserModified, "").Get();

                var business = new Business();
                business.Address = address;
                business.ABN = "123456789";
                business.AccountType = AccountType.Free;
                business.Email = "test@Ttest.com.au";
                business.Phone = "98209820";
                business.Name = "ME";
                business.UserModified = "ME";
              //  business.DateCreated = DateTime.Now;
                business.DateModified = DateTime.Now;
                business.LookupTaxCountry = ModelGenerator.GetAustralianTaxCountry();
                var validationContext = new ValidationContext(business, null, null);
                Validator.ValidateObject(business, validationContext);


            }



            [TestMethod()]
            [Microsoft.VisualStudio.TestTools.UnitTesting.ExpectedException(typeof (ValidationException))]
            public void ShouldFailWhenAddressIsNull()
            {

                var business = new Business
                                   {
                                       ABN = "123456789",
                                       AccountType = AccountType.Free,
                                       Email = "test@Ttest.com.au",
                                       Phone = "98209820",
                                       Address = null,
                                 //      UserCreated = "ME",
                                       UserModified = "ME",
                                  //     DateCreated = DateTime.Now,
                                       DateModified = DateTime.Now
                                   };

                var validationContext = new ValidationContext(business, null, null);
                Validator.ValidateObject(business, validationContext);

            }

            [TestMethod()]
            [Microsoft.VisualStudio.TestTools.UnitTesting.ExpectedException(typeof (ValidationException))]
            public void ShouldFailfullWhenEmailIsNotSupplied()
            {

                var session = AddressGenerationSessionFactory.CreateSession();
                var address = session.Single<Address>()
                    .Impose(x => x.Id, 0)
                 //   .Impose(x => x.DateCreated, new DateTime())
                    .Impose(x => x.DateModified, new DateTime())
                  ///  .Impose(x => x.UserCreated, "")
                    .Impose(x => x.UserModified, "").Get();

                var business = new Business();
                business.Address = address;
                business.ABN = "123456789";
                business.AccountType = AccountType.Free;
                business.Email = "";
                business.Phone = "98209820";
              //  business.UserCreated = "ME";
                business.UserModified = "ME";
               // business.DateCreated = DateTime.Now;
                business.DateModified = DateTime.Now;

                var validationContext = new ValidationContext(business, null, null);
                Validator.ValidateObject(business, validationContext);

            }


            [TestMethod()]
            [Microsoft.VisualStudio.TestTools.UnitTesting.ExpectedException(typeof (ValidationException))]
            public void ShouldFailWhenPhoneIsNotSupplied()
            {

                var session = AddressGenerationSessionFactory.CreateSession();
                var address = session.Single<Address>()
                    .Impose(x => x.Id, 0)
                   // .Impose(x => x.DateCreated, new DateTime())
                    .Impose(x => x.DateModified, new DateTime())
                //    .Impose(x => x.UserCreated, "")
                    .Impose(x => x.UserModified, "").Get();

                var business = new Business();
                business.Address = address;
                business.ABN = "123456789";
                business.AccountType = AccountType.Free;
                business.Email = "ifons@gmail.com";
                business.Phone = "";
               // business.UserCreated = "ME";
                business.UserModified = "ME";
               // business.DateCreated = DateTime.Now;
                business.DateModified = DateTime.Now;

                var validationContext = new ValidationContext(business, null, null);
                Validator.ValidateObject(business, validationContext);
            }

            [TestMethod()]
            [Microsoft.VisualStudio.TestTools.UnitTesting.ExpectedException(typeof (ValidationException))]
            public void ShouldFailWhenEmailAddressDoesNotContrainAtSign()
            {

                var session = AddressGenerationSessionFactory.CreateSession();
                var address = session.Single<Address>()
                    .Impose(x => x.Id, 0)
                   // .Impose(x => x.DateCreated, new DateTime())
                    .Impose(x => x.DateModified, new DateTime())
                   // .Impose(x => x.UserCreated, "")
                    .Impose(x => x.UserModified, "").Get();

                var business = new Business();
                business.Address = address;
                business.ABN = "123456789";
                business.AccountType = AccountType.Free;
                business.Email = "ifonsmail";
                business.Phone = "98209820";
               // business.UserCreated = "ME";
                business.UserModified = "ME";
               // business.DateCreated = DateTime.Now;
                business.DateModified = DateTime.Now;

                var validationContext = new ValidationContext(business, null, null);
                Validator.ValidateObject(business, validationContext);
            }



            [TestMethod()]
            [Microsoft.VisualStudio.TestTools.UnitTesting.ExpectedException(typeof (ValidationException))]
            public void ShouldFailWhenDateCreatedIsNotSupplied()
            {

                var session = AddressGenerationSessionFactory.CreateSession();
                var address = session.Single<Address>()
                    .Impose(x => x.Id, 0)
                    ////.Impose(x => x.DateCreated, new DateTime())
                    .Impose(x => x.DateModified, new DateTime())
                    //.Impose(x => x.UserCreated, "")
                    .Impose(x => x.UserModified, "").Get();

                var business = new Business();
                business.Address = address;
                business.ABN = "123456789";
                business.AccountType = AccountType.Free;
                business.Email = "ifonsmail";
                business.Phone = "98209820";
               // business.UserCreated = "ME";
                business.UserModified = "ME";
               // business.DateCreated = new DateTime();
                business.DateModified = DateTime.Now;

                var validationContext = new ValidationContext(business, null, null);
                Validator.ValidateObject(business, validationContext);
            }


        }





        [TestClass()]
        public class WhenEditBusiness
        {


            private TestContext testContextInstance;

            /// <summary>
            ///Gets or sets the test context which provides
            ///information about and functionality for the current test run.
            ///</summary>
            public Microsoft.VisualStudio.TestTools.UnitTesting.TestContext TestContext
            {
                get { return testContextInstance; }
                set { testContextInstance = value; }
            }



            [TestMethod()]
            public void ShouldBeSuccessfullWhenBusinessIsValid()
            {


                var business = new Business();
                business.Id = 34;
                business.Address = new Address {Id = 432};
                business.ABN = "123456789";
                business.AccountType = AccountType.Free;
                business.Email = "test@Ttest.com.au";
                business.Phone = "98209820";
                business.Name = "BusinessNameyo";
                business.UserModified = "ME";
               // business.DateCreated = DateTime.Now;
                business.DateModified = DateTime.Now;
                business.LookupTaxCountry = ModelGenerator.GetAustralianTaxCountry();
                var validationContext = new ValidationContext(business, null, null);
                Validator.ValidateObject(business, validationContext);


            }

            [TestMethod()]
            [Microsoft.VisualStudio.TestTools.UnitTesting.ExpectedException(typeof (ValidationException))]
            public void ShouldFailWhenAddressIsNull()
            {

                var business = new Business
                                   {
                                       Id = 32,
                                       ABN = "123456789",
                                       AccountType = AccountType.Free,
                                       Email = "test@Ttest.com.au",
                                       Phone = "98209820",
                                       Address = null,
                                      // UserCreated = "ME",
                                       UserModified = "ME",
                                     //  DateCreated = DateTime.Now,
                                       DateModified = DateTime.Now
                                   };

                var validationContext = new ValidationContext(business, null, null);
                Validator.ValidateObject(business, validationContext);

            }


            [TestMethod()]
            [Microsoft.VisualStudio.TestTools.UnitTesting.ExpectedException(typeof (ValidationException))]
            public void ShouldFailWhenAddressIdIsZero()
            {

                var business = new Business
                                   {
                                       Id = 432,
                                       ABN = "123456789",
                                       AccountType = AccountType.Free,
                                       Address = new Address {Id = 0},
                                       Email = "test@Ttest.com.au",
                                       Phone = "98209820",
                                     //  UserCreated = "ME",
                                       UserModified = "ME",
                                      // DateCreated = DateTime.Now,
                                       DateModified = DateTime.Now
                                   };

                var validationContext = new ValidationContext(business, null, null);
                Validator.ValidateObject(business, validationContext);

            }

            [TestMethod()]
            [Microsoft.VisualStudio.TestTools.UnitTesting.ExpectedException(typeof (ValidationException))]
            public void ShouldFailWhenAddressIdIsLessThanZero()
            {

                var business = new Business
                                   {
                                       Id = 432,
                                       ABN = "123456789",
                                       AccountType = AccountType.Free,
                                       Address = new Address {Id = -15},
                                       Email = "test@Ttest.com.au",
                                       Phone = "98209820",
                                     //  UserCreated = "ME",
                                       UserModified = "ME",
                                     //  DateCreated = DateTime.Now,
                                       DateModified = DateTime.Now
                                   };

                var validationContext = new ValidationContext(business, null, null);
                Validator.ValidateObject(business, validationContext);

            }

            [TestMethod()]
            public void ShouldPassWhenAddressIdIsNotZero()
            {

                var business = new Business
                                   {
                                       Id = 32,
                                       ABN = "123456789",
                                       AccountType = AccountType.Free,
                                       Address = new Address {Id = 543},
                                       Email = "test@Ttest.com.au",
                                       Phone = "98209820",
                                     //  UserCreated = "ME",
                                       UserModified = "ME",
                                       Name = "BUSINESSNAMEYO",
                                      // DateCreated = DateTime.Now,
                                       DateModified = DateTime.Now,
                                       LookupTaxCountry = ModelGenerator.GetAustralianTaxCountry()
                                      
                                   };

                var validationContext = new ValidationContext(business, null, null);
                Validator.ValidateObject(business, validationContext);

            }


        }

    }



